package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.key.RedisKey;
import cn.wolfcode.luowowo.cache.service.IStrategyStatsCacheService;
import cn.wolfcode.luowowo.cache.vo.StrategyStats;
import cn.wolfcode.luowowo.common.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatsCacheServiceImpl implements IStrategyStatsCacheService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public void setStrategyStats(StrategyStats ss) {
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(ss.getStrategyId());
        redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(ss));
    }

    public StrategyStats getStats(Long strategyId) {

        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        String json = redisTemplate.opsForValue().get(cacheKey);
        return JSON.parseObject(json, StrategyStats.class);
    }

    public void incr(Long strategyId, int num, int type) {
        StrategyStats stats = getStats(strategyId);
        switch (type) {
            case VIEWNUM_TYPE:
                stats.setViewnum(stats.getViewnum() + num);
                break;
            case REPLYNUM_TYPE:
                stats.setReplynum(stats.getReplynum() + num);
                break;
            case FAVORNUM_TYPE:
                stats.setFavornum(stats.getFavornum() + num);
                break;
            case THUMBSUPNUM_TYPE:
                stats.setThumbsupnum(stats.getThumbsupnum() + num);
                break;
        }
        setStrategyStats(stats);
    }

    public boolean noExist(Long strategyId) {
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        return !redisTemplate.hasKey(cacheKey);
    }

    public boolean favor(Long strategyId, Long userId) {
        boolean flag=false; //收藏成功.
        int num=0;  //偏移量问题

        List<Long> ids = new ArrayList<>();
        String cacheKey = RedisKey.STRATEGY_STATS_FAVOR.getCacheKey(userId);
        String arr = redisTemplate.opsForValue().get(cacheKey);

        if (arr != null) {
            //有收藏记录,解析收藏记录.
            ids = JSON.parseArray(arr, Long.class);
        }
        if (ids.contains(strategyId)) {
            //有收藏
            ids.remove(strategyId);
            num=-1;
        } else {
            //没有收藏
            ids.add(strategyId);
            num=1;
            flag=true; //收藏操作
        }
        //保存收藏记录
        redisTemplate.opsForValue().set(cacheKey,JSON.toJSONString(ids));
        //更新统计数据
        incr(strategyId,num,FAVORNUM_TYPE);
        return flag;
    }

    public boolean isFavor(Long userId, Long strategyId) {
        List<Long> ids = new ArrayList<>();
        String cacheKey = RedisKey.STRATEGY_STATS_FAVOR.getCacheKey(userId);
        String arr = redisTemplate.opsForValue().get(cacheKey);
        if(arr!=null){
            //有收藏记录,解析收藏记录.
             ids = JSON.parseArray(arr, Long.class);
        }
        return ids.contains(strategyId);
    }

    public boolean strategyThumbup(Long userId, Long strategyId) {
        boolean flag=false;
        String cacheKey = RedisKey.STRATEGY_STATS_THUMBUP.getCacheKey(userId + ":" + strategyId);
        String val = redisTemplate.opsForValue().get(cacheKey);
        if(val==null){
            //当天没有点赞
            Date now = new Date();
            Date end = DateUtil.getEndDate(now);
            long timeout = DateUtil.getDateBetween(now, end);

            redisTemplate.opsForValue().set(cacheKey,"",timeout, TimeUnit.MILLISECONDS);
            //统计点赞数
            incr(strategyId,1,THUMBSUPNUM_TYPE);
            flag=true;
        }
        return flag;
    }

    public List<StrategyStats> getAllStrategyStats() {

        List<StrategyStats> list = new ArrayList<>();
        //拿到所有统计对象的key
        Set<String> keys = redisTemplate.keys(RedisKey.STRATEGY_STATS.getCacheKey("*"));
        for (String key : keys) {
            //拿到统计对象的josn数据
            String json = redisTemplate.opsForValue().get(key);
            list.add(JSON.parseObject(json,StrategyStats.class));
        }

        return list;
    }
    //zrank key name -> 升序返回排名
    public boolean noExistRank(RedisKey key, Long strategyId) {
        String name = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        Long rank = redisTemplate.opsForZSet().rank(key.getPrefix(), name);

        return rank==null; //通过判断排名来决定是否存在.
    }

    //zincrby key num name -> 偏移名称对应的数值
    public void addRank(RedisKey key, int num, Long strategyId) {
        String name = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        //K key, V value, double delta
        redisTemplate.opsForZSet().incrementScore(key.getPrefix(),name,num);
    }

    public List<StrategyStats> listRankTop10(RedisKey key) {
        ValueOperations<String, String> opv = redisTemplate.opsForValue();

        List<StrategyStats> vos = new ArrayList<>();
        //返回排名前10的统计对象的 key.
        Set<String> ts = redisTemplate.opsForZSet().reverseRange(key.getPrefix(), 0, 9);
        for (String t : ts) {
            String json = opv.get(t);
            //统计对象json字符串转变成对象 ,存入集合.
            vos.add(JSON.parseObject(json,StrategyStats.class));
        }
        return vos;
    }


//    private void incrViewNum(Long strategyId, int num) {
//        //查到当前文章的热数据
//        StrategyStats stats = getStats(strategyId);
//        //修改值
//        stats.setViewnum(stats.getViewnum() + num);
//        //重新保存.
//        setStrategyStats(stats);
//    }
}
